﻿/****************************** Module Header ******************************\
 * Module Name:  FormsSkinHelper.cs
 * Module Version:  1.0.0 (2012-11-9)
 * Copyright (c) AnyEB.Com (14507247@qq.com)
 * 
 * This class is used to process the FormsSkinHelper.
 * 
 * This source is subject to the GPL License.
 * See http://www.gnu.org/licenses/gpl.html.
 * All other rights reserved.
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Xml.Linq;
using System.Xml.XPath;

namespace UCF.Core.Forms
{
    public class FormsSkinHelper
    {
        public IFormsSkin Skin { get; set; }

        public FormsSkinHelper(IFormsSkin skin)
        {
            Skin = skin;
        }

        public void SetSkin(Control.ControlCollection cc)
        {
            foreach (Control c1 in cc)
            {
                bool a = SetSkinFunc(c1);
                if (c1.Controls.Count > 0 && a) SetSkin(c1.Controls);
            }
        }
        /// <summary>
        /// 返回是否是一个标准容器
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        private bool SetSkinFunc(Control c)
        {
            if (c.GetType() == typeof(DataGridView))
            {
                DataGridView dgv = c as DataGridView;
                dgv.AutoGenerateColumns = false;
                dgv.SelectionMode = Skin.SelectionMode;
                dgv.BackgroundColor = Skin.DataGridViewBgColor;
                dgv.BorderStyle = Skin.DataGridViewBorderStyle;
                dgv.SetColumnHeadersStyle(Skin.DataGridViewColumnHeadersBgColor);
                if (Skin.AutoSetDataGridViewRowHeaders) dgv.SetRowHeaderIndex();
                return false;
            }
            if (c.GetType() == typeof(TabControl))
            {
                ((TabControl)c).SetTabBgColor(Skin.TabPageNormalBgColor, Skin.TagPageSelectedBgColor, Skin.TagPageFontColor);
                return true;
            }
            if (c.GetType() == typeof(Button))
            {
                // Button btn = (Button)c;
                //btn.BackColor = Skin.ButtonBgColor;
                //btn.ForeColor = Skin.ButtonForeColor;
                //btn.FlatStyle = FlatStyle.Flat;
                return false;
            }
            //if (c.GetType() == typeof(SplitContainer) || c.GetType() == typeof(Panel) || c.GetType() == typeof(FlowLayoutPanel)) c.BackColor = System.Drawing.Color.Transparent;
            return true;
        }

        /**
         * 2014-1-5 重构,支持外观文件定义,需增加Skin/TemplateName/UI.uif文件
        */
        private static XElement UIDoc;
        private static string SkinDir, skinConf;
        public static string ImageHoverTag { get; set; }
        public static string ImageClickTag { get; set; }
        public static string DefaultSkinID { get; set; }
        public static string CurrentSkinID { get; set; }
        public static bool Enable { get; set; }
        public static IList<string> Message { get; set; }

        public static void SwitchSkin(string skinid)
        {
            // 写入缓存
            CurrentSkinID = skinid;
            SaveConf(skinid);

            // 检测环境
            if (SkinDir == null) SkinDir = Application.StartupPath + "\\Skin\\" + skinid;
            string uifile = SkinDir + "\\UI.uif";
            if (!Directory.Exists(SkinDir) || !File.Exists(uifile))
            {
                Enable = false;
                Message.Add(string.Format("未设置主题样式![{0}]", skinid));
                return;
            }
            Enable = true;

            try
            {
                UIDoc = XElement.Load(uifile);
            }
            catch (Exception ex)
            {
                Message.Add(ex.Message);
                Enable = false;
                throw ex;
            }

        }

        private static string GetAttrValue(string id, string attrid, bool showErr = true, string[] tags = null)
        {
            if (!Enable) return null;
            XElement xe = UIDoc.XPathSelectElement(string.Format("//*[@id='{0}']", id));
            if (xe == null)
            {
                if (showErr) Message.Add(string.Format("id [{0}] 无索引!", id));
                return null;
            }
            if (xe.Attribute(attrid) == null)
            {
                if (showErr) Message.Add(string.Format("id [{0}] 资源文件不存在!", id));
                return null;
            }
            return tags == null ? xe.Attribute(attrid).Value : string.Format(xe.Attribute(attrid).Value, tags);
        }
        private static Image GetAltImageById(string id, string attrid, string altattrid, string suffix)
        {
            string path = GetAttrValue(id, attrid, false);
            if (string.IsNullOrEmpty(path)) path = GetAttrValue(id, altattrid);
            if (string.IsNullOrEmpty(path)) return null;
            if (!path.Contains('\\')) path = SkinDir + "\\" + path;
            string ext = Path.GetExtension(path);
            string path1 = path.Substring(0, path.LastIndexOf('.')) + suffix + ext;
            if (File.Exists(path1)) return Bitmap.FromFile(path1);
            if (!File.Exists(path)) return null;
            return Bitmap.FromFile(path);
        }

        public static Image GetImageById(string id, string attrid = "Image", string[] tags = null)
        {
            string path = GetAttrValue(id, attrid, true, tags);
            if (string.IsNullOrEmpty(path)) return null;
            if (!path.Contains('\\')) path = SkinDir + "\\" + path;
            if (!File.Exists(path)) return null;
            return Bitmap.FromFile(path);
        }

        public static Image GetImageHoverById(string id, string attrid = "ImageHover", string altattrid = "Image")
        {
            return GetAltImageById(id, attrid, altattrid, ImageHoverTag);
        }

        public static Image GetImageClickById(string id, string attrid = "ImageClick", string altattrid = "Image")
        {
            return GetAltImageById(id, attrid, altattrid, ImageClickTag);
        }

        public static Image GetBackgroundImageById(string id, string attrid = "BackgroundImage")
        {
            return GetImageById(id, attrid);
        }

        /// <summary>
        /// 2014-1-9 created by sutroon
        /// </summary>
        /// <param name="id"></param>
        /// <param name="attrid"></param>
        /// <returns></returns>
        public static Color GetColorById(string id, string attrid)
        {
            string color = GetAttrValue(id, attrid);
            if (string.IsNullOrEmpty(color)) return Color.Empty;
            try
            {
                if (color.StartsWith("#")) return ColorTranslator.FromHtml(color);
                if (color.Contains(','))
                {
                    string[] arr = color.Split(',');
                    return Color.FromArgb(arr[0].ToInt(), arr[1].ToInt(), arr[2].ToInt());
                }
                return Color.FromName(color);
            }
            catch (Exception ex)
            {
                Message.Add(ex.Message);
                return Color.Empty;
            }
        }
        public static Color GetBackColorById(string id)
        {
            return GetColorById(id, "BackColor");
        }

        /// <summary>
        /// 安装主题文件
        /// </summary>
        /// <param name="zip"></param>
        /// <param name="checkExists"></param>
        public static void Install(byte[] zip, bool checkExists = true)
        {
            // 初始化皮肤列表
            dtTimer = new System.Data.DataTable();
            dtTimer.Columns.Add("SkinID");
            dtTimer.Columns.Add("Begin", typeof(DateTime));
            dtTimer.Columns.Add("Finish", typeof(DateTime));


            // 初始化属性
            DefaultSkinID = "Default";
            ImageHoverTag = "_hover";
            ImageClickTag = "_click";
            Message = new List<string>();
            skinConf = Application.StartupPath + "\\Skin\\Skin.conf";

            // 建立目录
            string dir = Application.StartupPath + "\\Skin";
            if (!checkExists && Directory.Exists(dir)) return;
            FileHelper fh = new FileHelper();
            try
            {
                fh.UnZip(zip, dir);
            }
            catch (Exception)
            {
            }
        }

        static DataTable dtTimer;
        /// <summary>
        /// 添加计时器
        /// 2014-1-9 by sutroon
        /// </summary>
        /// <param name="dtBegin"></param>
        /// <param name="dtFinish"></param>
        /// <param name="skinid"></param>
        public static void AddTimer(DateTime dtBegin, DateTime dtFinish, string skinid)
        {
            dtTimer.Rows.Add(skinid, dtBegin, dtFinish);
        }

        public static void Read()
        {
            if (File.Exists(skinConf))
            {
                DefaultSkinID = File.ReadAllText(skinConf);
                SwitchSkin(DefaultSkinID);
                return;
            }
            if (dtTimer != null)
            {
                foreach (DataRow r in dtTimer.Rows)
                {
                    if (DateTime.Now > (DateTime)r[1] && DateTime.Now < (DateTime)r[2])
                    {
                        SwitchSkin(r[0].ToString());
                        return;
                    }
                }
            }
            SwitchSkin(DefaultSkinID);
        }

        /// <summary>
        /// 保存主题配置
        /// 2014-1-10 by sutroon
        /// </summary>
        /// <param name="skinid"></param>
        public static void SaveConf(string skinid)
        {
            File.WriteAllText(skinConf, skinid);
        }
    }
}
